å ç¢ãªããŒã¿ããŒã¹èšèšãšå¹ççãªããŒã¿æäœã®ããã«ãå€éšããŒç®¡çãå«ãPython SQLAlchemyã®ãªã¬ãŒã·ã§ã³ã·ãããç¿åŸããŸããããã¹ã±ãŒã©ãã«ãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®å®çšçãªäŸãšãã¹ããã©ã¯ãã£ã¹ãåŠã³ãŸãã
Python SQLAlchemyãªã¬ãŒã·ã§ã³ã·ããïŒå€éšããŒç®¡çã®å æ¬çã¬ã€ã
Python SQLAlchemyã¯ãéçºè ã«ããŒã¿ããŒã¹ãšã®å¯Ÿè©±ã®ããã®é«ã¬ãã«ãªæœè±¡åãæäŸãã匷åãªãªããžã§ã¯ããªã¬ãŒã·ã§ãã«ããããŒïŒORMïŒã§ãããSQLããŒã«ãããã§ããSQLAlchemyã广çã«äœ¿çšããããã®æãéèŠãªåŽé¢ã®1ã€ã¯ãããŒã¿ããŒã¹ããŒãã«éã®ãªã¬ãŒã·ã§ã³ã·ãããçè§£ãã管çããããšã§ãããã®ã¬ã€ãã§ã¯ãå€éšããŒç®¡çã«çŠç¹ãåœãŠãSQLAlchemyãªã¬ãŒã·ã§ã³ã·ããã®å æ¬çãªæŠèŠãæäŸããå ç¢ã§ã¹ã±ãŒã©ãã«ãªããŒã¿ããŒã¹ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®ç¥èãç¿åŸã§ããããã«ããŸãã
ãªã¬ãŒã·ã§ãã«ããŒã¿ããŒã¹ãšå€éšããŒã®çè§£
ãªã¬ãŒã·ã§ãã«ããŒã¿ããŒã¹ã¯ãå®çŸ©ããããªã¬ãŒã·ã§ã³ã·ãããæã€ããŒãã«ã«ããŒã¿ãæŽçãããšããæŠå¿µã«åºã¥ããŠããŸãããããã®ãªã¬ãŒã·ã§ã³ã·ããã¯ãä»ã®ããŒãã«ã®äž»ããŒãåç §ããããšã§ããŒãã«ãçµã³ã€ããå€éšããŒãéããŠç¢ºç«ãããŸãããã®æ§é ã¯ããŒã¿ã®äžè²«æ§ãä¿èšŒããå¹ççãªããŒã¿ååŸãšæäœãå¯èœã«ããŸããå®¶ç³»å³ã®ãããªãã®ã ãšèããŠãã ãããåå人ïŒããŒãã«ã®è¡ïŒã¯ã芪ïŒç°ãªãããŒãã«ã®å¥ã®è¡ïŒãæã€ãããããŸããããããã®éã®æ¥ç¶ãã€ãŸã芪åé¢ä¿ã¯ãå€éšããŒã«ãã£ãŠå®çŸ©ãããŸãã
äž»èŠãªæŠå¿µïŒ
- äž»ããŒïŒ ããŒãã«ã®åè¡ã®äžæãªèå¥åã
- å€éšããŒïŒ ããããŒãã«ã®åã§ãå¥ã®ããŒãã«ã®äž»ããŒãåç §ãããªã¬ãŒã·ã§ã³ã·ããã確ç«ãããã®ã
- äžå¯Ÿå€ãªã¬ãŒã·ã§ã³ã·ããïŒ ããããŒãã«ã®1ã€ã®ã¬ã³ãŒãããå¥ã®ããŒãã«ã®è€æ°ã®ã¬ã³ãŒãã«é¢é£ä»ããããŠããé¢ä¿ïŒäŸïŒ1人ã®èè ãå€ãã®æ¬ãæžãïŒã
- å€å¯Ÿäžãªã¬ãŒã·ã§ã³ã·ããïŒ ããããŒãã«ã®è€æ°ã®ã¬ã³ãŒãããå¥ã®ããŒãã«ã®1ã€ã®ã¬ã³ãŒãã«é¢é£ä»ããããŠããé¢ä¿ïŒäžå¯Ÿå€ã®éïŒã
- å€å¯Ÿå€ãªã¬ãŒã·ã§ã³ã·ããïŒ ããããŒãã«ã®è€æ°ã®ã¬ã³ãŒãããå¥ã®ããŒãã«ã®è€æ°ã®ã¬ã³ãŒãã«é¢é£ä»ããããŠããé¢ä¿ïŒäŸïŒçåŸãšã³ãŒã¹ïŒãéåžžãçµåããŒãã«ãé¢äžããŸãã
SQLAlchemyã®ã»ããã¢ããïŒããªãã®åºç€
ãªã¬ãŒã·ã§ã³ã·ããã«å ¥ãåã«ãSQLAlchemyãã»ããã¢ããããå¿ èŠããããŸããããã«ã¯ãå¿ èŠãªã©ã€ãã©ãªã®ã€ã³ã¹ããŒã«ãšããŒã¿ããŒã¹ãžã®æ¥ç¶ãå«ãŸããŸããåºæ¬çãªäŸã以äžã«ç€ºããŸãã
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
# Database connection string (replace with your actual database details)
DATABASE_URL = 'sqlite:///./test.db'
# Create the database engine
engine = create_engine(DATABASE_URL)
# Create a session class
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# Create a base class for declarative models
Base = declarative_base()
ãã®äŸã§ã¯ã`create_engine`ã䜿çšããŠSQLiteããŒã¿ããŒã¹ãžã®æ¥ç¶ã確ç«ããŠããŸãïŒããã¯PostgreSQLãMySQLããŸãã¯ãã®ä»ã®ãµããŒããããŠããããŒã¿ããŒã¹ã«é©çšã§ããŸãïŒã`SessionLocal`ã¯ããŒã¿ããŒã¹ãšå¯Ÿè©±ããã»ãã·ã§ã³ãäœæããŸãã`Base`ã¯ãããŒã¿ããŒã¹ã¢ãã«ãå®çŸ©ããããã®åºæ¬ã¯ã©ã¹ã§ãã
ããŒãã«ãšãªã¬ãŒã·ã§ã³ã·ããã®å®çŸ©
åºç€ãæŽã£ããšããã§ãããŒã¿ããŒã¹ããŒãã«ãšãã®éã®ãªã¬ãŒã·ã§ã³ã·ãããå®çŸ©ã§ããŸãã`Author`ãš`Book`ããŒãã«ã®ã·ããªãªãèããŠã¿ãŸããããèè ã¯å€ãã®æ¬ãæžãããšãã§ããŸããããã¯äžå¯Ÿå€ã®ãªã¬ãŒã·ã§ã³ã·ããã衚ããŸãã
class Author(Base):
__tablename__ = 'authors'
id = Column(Integer, primary_key=True, index=True)
name = Column(String)
books = relationship("Book", back_populates="author") # defines the one-to-many relationship
class Book(Base):
__tablename__ = 'books'
id = Column(Integer, primary_key=True, index=True)
title = Column(String)
author_id = Column(Integer, ForeignKey('authors.id')) # foreign key linking to Author table
author = relationship("Author", back_populates="books") # defines the many-to-one relationship
説æïŒ
- `Author`ãš`Book`ã¯ãããŒã¿ããŒã¹ããŒãã«ã衚ãã¯ã©ã¹ã§ãã
- `__tablename__`ïŒããŒã¿ããŒã¹å ã®ããŒãã«åãå®çŸ©ããŸãã
- `id`ïŒåããŒãã«ã®äž»ããŒã
- `author_id`ïŒ`Book`ããŒãã«å ã®å€éšããŒã§ã`Author`ããŒãã«ã®`id`ãåç §ããŸããããã«ãããªã¬ãŒã·ã§ã³ã·ããã確ç«ãããŸããSQLAlchemyã¯å¶çŽãšãªã¬ãŒã·ã§ã³ã·ãããèªåçã«åŠçããŸãã
- `relationship()`ïŒããã¯SQLAlchemyã®ãªã¬ãŒã·ã§ã³ã·ãã管çã®äžå¿ã§ããããŒãã«éã®ãªã¬ãŒã·ã§ã³ã·ãããå®çŸ©ããŸãã
- `"Book"`ïŒé¢é£ããã¯ã©ã¹ïŒBookïŒãæå®ããŸãã
- `back_populates="author"`ïŒããã¯åæ¹åãªã¬ãŒã·ã§ã³ã·ããã«ãšã£ãŠéèŠã§ãã`Book`ã¯ã©ã¹ã«`Author`ã¯ã©ã¹ãæããªã¬ãŒã·ã§ã³ã·ãããäœæããŸãã`author.books`ã«ã¢ã¯ã»ã¹ãããšãSQLAlchemyã¯é¢é£ãããã¹ãŠã®æ¬ãããŒãããå¿ èŠãããããšãäŒããŸãã
- `Book`ã¯ã©ã¹ã§ã¯ã`relationship("Author", back_populates="books")`ãåæ§ã§ãããéæ¹åã§ããæ¬ã®èè ïŒbook.authorïŒã«ã¢ã¯ã»ã¹ã§ããããã«ããŸãã
ããŒã¿ããŒã¹ã«ããŒãã«ãäœæããïŒ
Base.metadata.create_all(bind=engine)
ãªã¬ãŒã·ã§ã³ã·ããã®æäœïŒCRUDãªãã¬ãŒã·ã§ã³
次ã«ããããã®ã¢ãã«ã«å¯ŸããŠäžè¬çãªCRUDïŒäœæãèªã¿åããæŽæ°ãåé€ïŒæäœãå®è¡ããŠã¿ãŸãããã
äœæïŒ
# Create a session
session = SessionLocal()
# Create an author
author1 = Author(name='Jane Austen')
# Create a book and associate it with the author
book1 = Book(title='Pride and Prejudice', author=author1)
# Add both to the session
session.add_all([author1, book1])
# Commit the changes to the database
session.commit()
# Close the session
session.close()
èªã¿åãïŒ
session = SessionLocal()
# Retrieve an author and their books
author = session.query(Author).filter_by(name='Jane Austen').first()
if author:
print(f"Author: {author.name}")
for book in author.books:
print(f" - Book: {book.title}")
else:
print("Author not found")
session.close()
æŽæ°ïŒ
session = SessionLocal()
# Retrieve the author
author = session.query(Author).filter_by(name='Jane Austen').first()
if author:
author.name = 'Jane A. Austen'
session.commit()
print("Author name updated")
else:
print("Author not found")
session.close()
åé€ïŒ
session = SessionLocal()
# Retrieve the author
author = session.query(Author).filter_by(name='Jane A. Austen').first()
if author:
session.delete(author)
session.commit()
print("Author deleted")
else:
print("Author not found")
session.close()
äžå¯Ÿå€ãªã¬ãŒã·ã§ã³ã·ããã®è©³çް
äžå¯Ÿå€ãªã¬ãŒã·ã§ã³ã·ããã¯åºæ¬çãªãã¿ãŒã³ã§ããäžèšã®äŸã¯ãã®åºæ¬çãªæ©èœã瀺ããŠããŸããããã«è©³ããèŠãŠãããŸãããã
ã«ã¹ã±ãŒãåé€ïŒ èè ãåé€ãããå Žåããã®æ¬ã¯ã©ããªãã¹ãã§ããããïŒSQLAlchemyã§ã¯ãã«ã¹ã±ãŒãåäœãèšå®ã§ããŸãã
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
DATABASE_URL = 'sqlite:///./test_cascade.db'
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
class Author(Base):
__tablename__ = 'authors'
id = Column(Integer, primary_key=True, index=True)
name = Column(String)
books = relationship("Book", back_populates="author", cascade="all, delete-orphan") # Cascade delete
class Book(Base):
__tablename__ = 'books'
id = Column(Integer, primary_key=True, index=True)
title = Column(String)
author_id = Column(Integer, ForeignKey('authors.id'))
author = relationship("Author", back_populates="books")
Base.metadata.create_all(bind=engine)
`Author`ã¯ã©ã¹ã®`relationship`å®çŸ©ã«ãã`cascade="all, delete-orphan"`åŒæ°ã¯ãèè ãåé€ããããšãã«ãé¢é£ãããã¹ãŠã®æ¬ãåé€ãããããšãæå®ããŸãã`delete-orphan`ã¯ãå€ç«ããæ¬ïŒèè ã®ããªãæ¬ïŒãåé€ããŸãã
é å»¶èªã¿èŸŒã¿ vs. ç©æ¥µçãªèªã¿èŸŒã¿ïŒ
- é å»¶èªã¿èŸŒã¿ïŒããã©ã«ãïŒïŒ `author.books`ã«ã¢ã¯ã»ã¹ãããšãSQLAlchemyã¯`books`屿§ã«ã¢ã¯ã»ã¹ããããšãããšãã«*ã®ã¿*ããŒã¿ããŒã¹ãã¯ãšãªããŸããé¢é£ããŒã¿ãåžžã«å¿ èŠã§ãªãå Žåã¯å¹ççã§ããããN+1ã¯ãšãªåé¡ãïŒ1ã€ã®ã¯ãšãªã§æžãå Žåã«è€æ°ã®ããŒã¿ããŒã¹ã¯ãšãªãå®è¡ããããšïŒã«ã€ãªããå¯èœæ§ããããŸãã
- ç©æ¥µçãªèªã¿èŸŒã¿ïŒ SQLAlchemyã¯ã芪ãªããžã§ã¯ããšåãã¯ãšãªã§é¢é£ããŒã¿ããã§ããããŸããããã«ãããããŒã¿ããŒã¹ã¯ãšãªã®æ°ãæžããããšãã§ããŸãã
ç©æ¥µçãªèªã¿èŸŒã¿ã¯ã`relationship`åŒæ°ïŒ`lazy='joined'`ã`lazy='subquery'`ã`lazy='select'`ïŒã䜿çšããŠèšå®ã§ããŸããæé©ãªã¢ãããŒãã¯ãç¹å®ã®ããŒãºãšããŒã¿ã»ããã®ãµã€ãºã«ãã£ãŠç°ãªããŸããäŸãã°ïŒ
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
DATABASE_URL = 'sqlite:///./test_eager.db'
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
class Author(Base):
__tablename__ = 'authors'
id = Column(Integer, primary_key=True, index=True)
name = Column(String)
books = relationship("Book", back_populates="author", lazy='joined') # Eager loading
class Book(Base):
__tablename__ = 'books'
id = Column(Integer, primary_key=True, index=True)
title = Column(String)
author_id = Column(Integer, ForeignKey('authors.id'))
author = relationship("Author", back_populates="books")
Base.metadata.create_all(bind=engine)
ãã®å Žåã`lazy='joined'`ã¯ãèè ãšåãã¯ãšãªã§æ¬ãããŒãããããšè©Šã¿ãããŒã¿ããŒã¹ãžã®åŸåŸ©åæ°ãæžãããŸãã
å€å¯Ÿäžãªã¬ãŒã·ã§ã³ã·ãã
å€å¯Ÿäžãªã¬ãŒã·ã§ã³ã·ããã¯ãäžå¯Ÿå€ãªã¬ãŒã·ã§ã³ã·ããã®éã§ããå€ãã®ã¢ã€ãã ã1ã€ã®ã«ããŽãªã«å±ããŠãããšèãããšããããããã§ããããäžèšã®`Book`ãã`Author`ãžã®äŸã¯ã*æé»çã«*å€å¯Ÿäžãªã¬ãŒã·ã§ã³ã·ããã瀺ããŠããŸããè€æ°ã®æ¬ã1人ã®èè ã«å±ããããšãã§ããŸãã
äŸïŒæžç±/èè äŸã®ç¹°ãè¿ãïŒïŒ
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
DATABASE_URL = 'sqlite:///./test_many_to_one.db'
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
class Author(Base):
__tablename__ = 'authors'
id = Column(Integer, primary_key=True, index=True)
name = Column(String)
books = relationship("Book", back_populates="author")
class Book(Base):
__tablename__ = 'books'
id = Column(Integer, primary_key=True, index=True)
title = Column(String)
author_id = Column(Integer, ForeignKey('authors.id'))
author = relationship("Author", back_populates="books")
Base.metadata.create_all(bind=engine)
ãã®äŸã§ã¯ã`Book`ã¯ã©ã¹ã«ã¯`author_id`å€éšããŒãå«ãŸããŠãããå€å¯Ÿäžãªã¬ãŒã·ã§ã³ã·ããã確ç«ããŠããŸãã`Book`ã¯ã©ã¹ã®`author`屿§ã¯ã忬ã«é¢é£ä»ããããèè ãžã®ç°¡åãªã¢ã¯ã»ã¹ãæäŸããŸãã
å€å¯Ÿå€ãªã¬ãŒã·ã§ã³ã·ãã
å€å¯Ÿå€ãªã¬ãŒã·ã§ã³ã·ããã¯ããè€éã§ãçµåããŒãã«ïŒãŸãã¯ããããããŒãã«ïŒãå¿ èŠã§ããçåŸãšã³ãŒã¹ã®å€å žçãªäŸãèããŠã¿ãŸããããçåŸã¯å€ãã®ã³ãŒã¹ã«ç»é²ã§ããã³ãŒã¹ã«ã¯å€ãã®çåŸãããŸãã
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, Table
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
DATABASE_URL = 'sqlite:///./test_many_to_many.db'
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
# Junction table for students and courses
student_courses = Table('student_courses', Base.metadata,
Column('student_id', Integer, ForeignKey('students.id'), primary_key=True),
Column('course_id', Integer, ForeignKey('courses.id'), primary_key=True)
)
class Student(Base):
__tablename__ = 'students'
id = Column(Integer, primary_key=True, index=True)
name = Column(String)
courses = relationship("Course", secondary=student_courses, back_populates="students")
class Course(Base):
__tablename__ = 'courses'
id = Column(Integer, primary_key=True, index=True)
name = Column(String)
students = relationship("Student", secondary=student_courses, back_populates="courses")
Base.metadata.create_all(bind=engine)
説æïŒ
- `student_courses`ïŒããã¯çµåããŒãã«ã§ããããã«ã¯`student_id`ãš`course_id`ã®2ã€ã®å€éšããŒãå«ãŸããŠããŸãã`Column`å®çŸ©ã®`primary_key=True`ã¯ãããããçµåããŒãã«ã®äž»ããŒã§ããããšã瀺ããŠããŸãïŒãããã£ãŠãå€éšããŒãšããŠãæ©èœããŸãïŒã
- `Student.courses`ïŒ`secondary=student_courses`åŒæ°ãéããŠ`Course`ã¯ã©ã¹ãžã®ãªã¬ãŒã·ã§ã³ã·ãããå®çŸ©ããŸãã`back_populates="students"`ã¯ã`Course`ã¯ã©ã¹ãã`Student`ãžã®éåç §ãäœæããŸãã
- `Course.students`ïŒ`Student.courses`ãšåæ§ã«ã`Course`åŽããã®ãªã¬ãŒã·ã§ã³ã·ãããå®çŸ©ããŸãã
äŸïŒçåŸãšã³ãŒã¹ã®é¢é£ä»ãã®è¿œå ãšååŸïŒ
session = SessionLocal()
# Create students and courses
student1 = Student(name='Alice')
course1 = Course(name='Math')
# Associate student with course
student1.courses.append(course1) # or course1.students.append(student1)
# Add to the session and commit
session.add(student1)
session.commit()
# Retrieve the courses for a student
student = session.query(Student).filter_by(name='Alice').first()
if student:
print(f"Student: {student.name} is enrolled in:")
for course in student.courses:
print(f" - {course.name}")
session.close()
ãªã¬ãŒã·ã§ã³ã·ããèªã¿èŸŒã¿æŠç¥ïŒããã©ãŒãã³ã¹ã®æé©å
ç©æ¥µçãªèªã¿èŸŒã¿ã§åè¿°ããããã«ããªã¬ãŒã·ã§ã³ã·ããã®èªã¿èŸŒã¿æ¹æ³ã¯ãç¹ã«å€§èŠæš¡ãªããŒã¿ã»ãããæ±ãå Žåã«ãã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ã«å€§ãã圱é¿ããå¯èœæ§ããããŸããé©åãªèªã¿èŸŒã¿æŠç¥ãéžæããããšã¯ãæé©åã«ãšã£ãŠéåžžã«éèŠã§ããããã§ã¯ãäžè¬çãªæŠç¥ã«ã€ããŠããã«è©³ããèŠãŠãããŸãã
1. é å»¶èªã¿èŸŒã¿ïŒããã©ã«ãïŒïŒ
- SQLAlchemyã¯ãé¢é£ãªããžã§ã¯ãã«ã¢ã¯ã»ã¹ãããšãïŒäŸïŒ`author.books`ïŒã«ã®ã¿ããããããŒãããŸãã
- å©ç¹ïŒ äœ¿ãæ¹ãç°¡åã§ãå¿ èŠãªããŒã¿ã®ã¿ãããŒãããŸãã
- æ¬ ç¹ïŒ å€ãã®è¡ã«å¯ŸããŠé¢é£ãªããžã§ã¯ãã«ã¢ã¯ã»ã¹ããå¿ èŠãããå ŽåããN+1ã¯ãšãªåé¡ãã«ã€ãªããå¯èœæ§ããããŸããããã¯ãã¡ã€ã³ãªããžã§ã¯ããååŸããããã«1ã€ã®ã¯ãšãªãå®è¡ãããã®åŸã*n*åã®çµæã«å¯ŸããŠé¢é£ãªããžã§ã¯ããååŸããããã«*n*åã®ã¯ãšãªãå®è¡ããããšã«ãªãå¯èœæ§ãããããšãæå³ããŸããããã¯ããã©ãŒãã³ã¹ãèããäœäžãããå¯èœæ§ããããŸãã
- ãŠãŒã¹ã±ãŒã¹ïŒ é¢é£ããŒã¿ãåžžã«å¿ èŠã§ã¯ãªãå ŽåããããŒã¿ãæ¯èŒçå°ããå Žåã
2. ç©æ¥µçãªèªã¿èŸŒã¿ïŒ
- SQLAlchemyã¯ãé¢é£ãªããžã§ã¯ãã芪ãªããžã§ã¯ããšåãã¯ãšãªã§ããŒãããããŒã¿ããŒã¹ã®åŸåŸ©åæ°ãæžãããŸãã
- ç©æ¥µçãªèªã¿èŸŒã¿ã®çš®é¡ïŒ
- çµåèªã¿èŸŒã¿ïŒ`lazy='joined'`ïŒïŒSQLã¯ãšãªã§`JOIN`å¥ã䜿çšããŸããåçŽãªãªã¬ãŒã·ã§ã³ã·ããã«é©ããŠããŸãã
- ãµãã¯ãšãªèªã¿èŸŒã¿ïŒ`lazy='subquery'`ïŒïŒãµãã¯ãšãªã䜿çšããŠé¢é£ãªããžã§ã¯ãããã§ããããŸããããè€éãªãªã¬ãŒã·ã§ã³ã·ãããç¹ã«è€æ°ã®ã¬ãã«ã®ãªã¬ãŒã·ã§ã³ã·ãããæã€å Žåã«å¹ççã§ãã
- éžæããŒã¹ã®ç©æ¥µçãªèªã¿èŸŒã¿ïŒ`lazy='select'`ïŒïŒæåã®ã¯ãšãªã®åŸã«å¥ã®ã¯ãšãªã§é¢é£ãªããžã§ã¯ããããŒãããŸããJOINãéå¹çãªå Žåããé¢é£ãªããžã§ã¯ãã«ãã£ã«ã¿ãªã³ã°ãé©çšããå¿ èŠãããå Žåã«é©ããŠããŸããåºæ¬çãªã±ãŒã¹ã§ã¯çµåèªã¿èŸŒã¿ããµãã¯ãšãªèªã¿èŸŒã¿ãããå¹çã¯å£ããŸãããããæè»æ§ããããŸãã
- å©ç¹ïŒ ããŒã¿ããŒã¹ã¯ãšãªã®æ°ãæžãããããã©ãŒãã³ã¹ãåäžãããŸãã
- æ¬ ç¹ïŒ å¿ èŠä»¥äžã«å€ãã®ããŒã¿ããã§ããããå¯èœæ§ãããããªãœãŒã¹ã®ç¡é§ã«ãªãããšããããŸããããè€éãªSQLã¯ãšãªã«ãªãå¯èœæ§ããããŸãã
- ãŠãŒã¹ã±ãŒã¹ïŒ é¢é£ããŒã¿ãé »ç¹ã«å¿ èŠã§ãããããã©ãŒãã³ã¹äžã®ã¡ãªãããäœåãªããŒã¿ã®ãã§ããã®å¯èœæ§ãäžåãå Žåã
3. èªã¿èŸŒã¿ãªãïŒ`lazy='noload'`ïŒïŒ
- é¢é£ãªããžã§ã¯ãã¯èªåçã«*ããŒããããŸãã*ãé¢é£å±æ§ã«ã¢ã¯ã»ã¹ãããš`AttributeError`ãçºçããŸãã
- å©ç¹ïŒ ãªã¬ãŒã·ã§ã³ã·ããã®å¶çºçãªèªã¿èŸŒã¿ãé²ãã®ã«åœ¹ç«ã¡ãŸããé¢é£ããŒã¿ããã€ããŒããããããæç€ºçã«å¶åŸ¡ã§ããŸãã
- æ¬ ç¹ïŒ é¢é£ããŒã¿ãå¿ èŠãªå Žåãä»ã®ææ³ã䜿çšããŠæåã§ããŒãããå¿ èŠããããŸãã
- ãŠãŒã¹ã±ãŒã¹ïŒ èªã¿èŸŒã¿ããã现ããå¶åŸ¡ãããå Žåããç¹å®ã®ã³ã³ããã¹ãã§ã®å¶çºçãªèªã¿èŸŒã¿ãé²ãããå Žåã
4. åçèªã¿èŸŒã¿ïŒ`lazy='dynamic'`ïŒïŒ
- é¢é£ã³ã¬ã¯ã·ã§ã³ã®ä»£ããã«ã¯ãšãªãªããžã§ã¯ããè¿ããŸããããã«ãããé¢é£ããŒã¿ããã§ããããã*å*ã«ããã£ã«ã¿ãªã³ã°ãããŒãžããŒã·ã§ã³ããã®ä»ã®ã¯ãšãªæäœãé©çšã§ããŸãã
- å©ç¹ïŒ é¢é£ããŒã¿ã®ååŸãåçã«ãã£ã«ã¿ãªã³ã°ããæé©åã§ããŸãã
- æ¬ ç¹ïŒ æšæºçãªé å»¶èªã¿èŸŒã¿ãç©æ¥µçãªèªã¿èŸŒã¿ãšæ¯èŒããŠãããè€éãªã¯ãšãªæ§ç¯ãå¿ èŠã§ãã
- ãŠãŒã¹ã±ãŒã¹ïŒ é¢é£ãªããžã§ã¯ãããã£ã«ã¿ãªã³ã°ãŸãã¯ããŒãžããŒã·ã§ã³ããå¿ èŠãããå Žåã«äŸ¿å©ã§ããé¢é£ããŒã¿ãååŸããæ¹æ³ã«æè»æ§ãæäŸããŸãã
é©åãªæŠç¥ã®éžæïŒ æé©ãªæŠç¥ã¯ãããŒã¿ã»ããã®ãµã€ãºãé¢é£ããŒã¿ãå¿ èŠãšãªãé »åºŠããªã¬ãŒã·ã§ã³ã·ããã®è€éããªã©ã®èŠå ã«ãã£ãŠç°ãªããŸãã以äžãèæ ®ããŠãã ããã
- é¢é£ããŒã¿ããã¹ãŠé »ç¹ã«å¿ èŠãšãªãå ŽåïŒ ç©æ¥µçãªèªã¿èŸŒã¿ïŒçµåèªã¿èŸŒã¿ãŸãã¯ãµãã¯ãšãªèªã¿èŸŒã¿ïŒããã°ãã°è¯ãéžæã§ãã
- é¢é£ããŒã¿ãå¿ èŠãªå Žåãšããã§ãªãå Žåãããå ŽåïŒ é å»¶èªã¿èŸŒã¿ãè¯ãåºçºç¹ã§ããN+1åé¡ã«æ³šæããŠãã ããã
- é¢é£ããŒã¿ããã£ã«ã¿ãªã³ã°ãŸãã¯ããŒãžããŒã·ã§ã³ããå¿ èŠãããå ŽåïŒ åçèªã¿èŸŒã¿ã¯å€§ããªæè»æ§ãæäŸããŸãã
- éåžžã«å€§èŠæš¡ãªããŒã¿ã»ããã®å ŽåïŒ åæŠç¥ã®å«æãæ éã«æ€èšããç°ãªãã¢ãããŒãã§ãã³ããããŒã¯ãè¡ã£ãŠãã ããããã£ãã·ã³ã°ã®äœ¿çšããããŒã¿ããŒã¹ã®è² è·ã軜æžããããã®è²Žéãªãã¯ããã¯ãšãªãåŸãŸãã
ãªã¬ãŒã·ã§ã³ã·ããã®åäœã®ã«ã¹ã¿ãã€ãº
SQLAlchemyã¯ãç¹å®ã®ããŒãºã«åãããŠãªã¬ãŒã·ã§ã³ã·ããã®åäœãã«ã¹ã¿ãã€ãºããããã®ããã€ãã®æ¹æ³ãæäŸããŸãã
1. ã¢ãœã·ãšãŒã·ã§ã³ãããã·ïŒ
- ã¢ãœã·ãšãŒã·ã§ã³ãããã·ã¯ãå€å¯Ÿå€ãªã¬ãŒã·ã§ã³ã·ããã®æäœãç°¡çŽ åããŸããçµåããŒãã«ãä»ããŠé¢é£ãªããžã§ã¯ãã®å±æ§ã«çŽæ¥ã¢ã¯ã»ã¹ã§ããããã«ããŸãã
- äŸïŒçåŸ/ã³ãŒã¹ã®äŸãç¶ããïŒ
- äžèšã®äŸã§ã¯ã`student_courses`ã«ãgradeãåã远å ããŸããã`grades = association_proxy('courses', 'student_courses.grade')`ã®è¡ã«ããã`student.grades`屿§ãéããŠæçžŸã«çŽæ¥ã¢ã¯ã»ã¹ã§ããŸããããã§`student.grades`ã䜿ã£ãŠæçžŸã®ãªã¹ããååŸãããã`student.grades`ã倿ŽããŠæçžŸãå²ãåœãŠããæŽæ°ãããã§ããŸãã
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, Table
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.associationproxy import association_proxy
DATABASE_URL = 'sqlite:///./test_association.db'
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
student_courses = Table('student_courses', Base.metadata,
Column('student_id', Integer, ForeignKey('students.id'), primary_key=True),
Column('course_id', Integer, ForeignKey('courses.id'), primary_key=True),
Column('grade', String) # Add grade column to the junction table
)
class Student(Base):
__tablename__ = 'students'
id = Column(Integer, primary_key=True, index=True)
name = Column(String)
courses = relationship("Course", secondary=student_courses, back_populates="students")
grades = association_proxy('courses', 'student_courses.grade') # association proxy
class Course(Base):
__tablename__ = 'courses'
id = Column(Integer, primary_key=True, index=True)
name = Column(String)
students = relationship("Student", secondary=student_courses, back_populates="courses")
Base.metadata.create_all(bind=engine)
2. ã«ã¹ã¿ã å€éšããŒå¶çŽïŒ
- ããã©ã«ãã§ã¯ãSQLAlchemyã¯`ForeignKey`å®çŸ©ã«åºã¥ããŠå€éšããŒå¶çŽãäœæããŸãã
- ãããã®å¶çŽã®åäœïŒäŸïŒ`ON DELETE CASCADE`ã`ON UPDATE CASCADE`ïŒã¯ãéåžžã¯å¿ èŠãããŸãããã`ForeignKeyConstraint`ãªããžã§ã¯ããçŽæ¥äœ¿çšããŠã«ã¹ã¿ãã€ãºã§ããŸãã
- äŸïŒããŸãäžè¬çã§ã¯ãããŸãããã説æã®ããïŒïŒ
- ãã®äŸã§ã¯ã`ForeignKeyConstraint`ã¯`ondelete='CASCADE'`ã䜿çšããŠå®çŸ©ãããŠããŸããããã¯ã`Parent`ã¬ã³ãŒããåé€ããããšãé¢é£ãããã¹ãŠã®`Child`ã¬ã³ãŒããåé€ãããããšãæå³ããŸãããã®åäœã¯ã以åã«ç€ºãã`cascade="all, delete-orphan"`æ©èœãšåãã§ãã
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, ForeignKeyConstraint
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
DATABASE_URL = 'sqlite:///./test_constraint.db'
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
class Parent(Base):
__tablename__ = 'parents'
id = Column(Integer, primary_key=True)
name = Column(String)
children = relationship('Child', back_populates='parent')
class Child(Base):
__tablename__ = 'children'
id = Column(Integer, primary_key=True)
name = Column(String)
parent_id = Column(Integer)
parent = relationship('Parent', back_populates='children')
__table_args__ = (ForeignKeyConstraint([parent_id], [Parent.id], ondelete='CASCADE'),) # Custom constraint
Base.metadata.create_all(bind=engine)
3. ãªã¬ãŒã·ã§ã³ã·ããã§ã®ãã€ããªãã屿§ã®äœ¿çšïŒ
- ãã€ããªãã屿§ã䜿çšãããšãããŒã¿ããŒã¹åã¢ã¯ã»ã¹ãšPythonã¡ãœãããçµã¿åãããŠãèšç®ãããããããã£ãäœæã§ããŸãã
- ãªã¬ãŒã·ã§ã³ã·ããããŒã¿ã«é¢é£ããèšç®ã掟ç屿§ã«åœ¹ç«ã¡ãŸãã
- äŸïŒèè ã«ãã£ãŠæžãããæ¬ã®ç·æ°ãèšç®ããã
- ãã®äŸã§ã¯ã`book_count`ã¯ãã€ããªããããããã£ã§ããããã¯ãèè ã«ãã£ãŠæžãããæ¬ã®æ°ãååŸã§ããPythonã¬ãã«ã®é¢æ°ã§ãã
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.hybrid import hybrid_property
DATABASE_URL = 'sqlite:///./test_hybrid.db'
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
class Author(Base):
__tablename__ = 'authors'
id = Column(Integer, primary_key=True, index=True)
name = Column(String)
books = relationship("Book", back_populates="author")
@hybrid_property
def book_count(self):
return len(self.books)
class Book(Base):
__tablename__ = 'books'
id = Column(Integer, primary_key=True, index=True)
title = Column(String)
author_id = Column(Integer, ForeignKey('authors.id'))
author = relationship("Author", back_populates="books")
Base.metadata.create_all(bind=engine)
ã°ããŒãã«ã¢ããªã±ãŒã·ã§ã³ã®ããã®ãã¹ããã©ã¯ãã£ã¹ãšèæ ®äºé
SQLAlchemyã䜿çšããŠã°ããŒãã«ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããéã«ã¯ãããã©ãŒãã³ã¹ãšã¹ã±ãŒã©ããªãã£ã«åœ±é¿ãäžããå¯èœæ§ã®ããèŠå ãèæ ®ããããšãéèŠã§ãã
- ããŒã¿ããŒã¹ã®éžæïŒ ä¿¡é Œæ§ãé«ãã¹ã±ãŒã©ãã«ã§ãåœéæåã»ããïŒUTF-8ãäžå¯æ¬ ïŒãååã«ãµããŒãããããŒã¿ããŒã¹ã·ã¹ãã ãéžæããŠãã ãããå ·äœçãªããŒãºãšã€ã³ãã©ã¹ãã©ã¯ãã£ã«åºã¥ããŠãPostgreSQLãMySQLãªã©ãäžè¬çãªéžæè¢ã§ãã
- ããŒã¿æ€èšŒïŒ ããŒã¿ã®äžè²«æ§ã®åé¡ã鲿¢ããããã«ãå ç¢ãªããŒã¿æ€èšŒãå®è£ ããŠãã ããããã¹ãŠã®å°åãšèšèªããã®å ¥åãæ€èšŒããã¢ããªã±ãŒã·ã§ã³ã倿§ãªããŒã¿ãæ£ããåŠçããããšã確èªããŠãã ããã
- æåãšã³ã³ãŒãã£ã³ã°ïŒ å¹ åºãèšèªãšæåããµããŒãããããã«ãããŒã¿ããŒã¹ãšã¢ããªã±ãŒã·ã§ã³ãUnicodeïŒUTF-8ïŒãæ£ããåŠçããããšã確èªããŠãã ãããããŒã¿ããŒã¹æ¥ç¶ãUTF-8ã䜿çšããããã«é©åã«æ§æããŠãã ããã
- ã¿ã€ã ãŸãŒã³ïŒ ã¿ã€ã ãŸãŒã³ãæ£ããåŠçããŠãã ããããã¹ãŠã®æ¥ä»/æå»å€ãUTCã§ä¿åãã衚瀺ã®ããã«ãŠãŒã¶ãŒã®ããŒã«ã«ã¿ã€ã ãŸãŒã³ã«å€æããŠãã ãããSQLAlchemyã¯`DateTime`åããµããŒãããŠããŸãããã¢ããªã±ãŒã·ã§ã³ããžãã¯ã§ã¿ã€ã ãŸãŒã³å€æãåŠçããå¿ èŠããããŸãã`pytz`ã®ãããªã©ã€ãã©ãªã®äœ¿çšãæ€èšããŠãã ããã
- ããŒã«ãªãŒãŒã·ã§ã³ïŒl10nïŒãšåœéåïŒi18nïŒïŒ ã¢ããªã±ãŒã·ã§ã³ã容æã«ããŒã«ã©ã€ãºã§ããããã«èšèšããŠãã ããããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ããã¹ãã®ç¿»èš³ã管çããããã«gettextãŸãã¯åæ§ã®ã©ã€ãã©ãªã䜿çšããŠãã ããã
- é貚æç®ïŒ ã¢ããªã±ãŒã·ã§ã³ãé貚å€ãåŠçããå Žåãé©åãªããŒã¿åïŒäŸïŒ`Decimal`ïŒã䜿çšããçºæ¿ã¬ãŒãAPIãšã®çµ±åãæ€èšããŠãã ããã
- ãã£ãã·ã³ã°ïŒ ç¹ã«é »ç¹ã«ã¢ã¯ã»ã¹ãããããŒã¿ã®ããã«ãããŒã¿ããŒã¹ã®è² è·ã軜æžããããã«ãã£ãã·ã³ã°ïŒäŸïŒRedisãMemcachedã®äœ¿çšïŒãå®è£ ããŠãã ããããã£ãã·ã³ã°ã¯ãããŸããŸãªå°åã®ããŒã¿ãæ±ãã°ããŒãã«ã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãå€§å¹ ã«åäžãããããšãã§ããŸãã
- ããŒã¿ããŒã¹æ¥ç¶ããŒãªã³ã°ïŒ ããŒã¿ããŒã¹æ¥ç¶ãå¹ççã«ç®¡çããããã©ãŒãã³ã¹ãåäžãããããã«ãæ¥ç¶ããŒã«ïŒSQLAlchemyã¯çµã¿èŸŒã¿ã®æ¥ç¶ããŒã«ãæäŸããŸãïŒã䜿çšããŠãã ããã
- ããŒã¿ããŒã¹èšèšïŒ ããŒã¿ããŒã¹ã¹ããŒããæ éã«èšèšããŠãã ãããç¹ã«å€éšããŒãšé¢é£ããŒãã«ãå«ãã¯ãšãªã®ããã©ãŒãã³ã¹ãæé©åããããã«ãããŒã¿æ§é ãšãªã¬ãŒã·ã§ã³ã·ãããèæ ®ããŠãã ãããã€ã³ããã¯ã¹æŠç¥ãæ éã«éžæããŠãã ããã
- ã¯ãšãªæé©åïŒ ã¯ãšãªããããã¡ã€ã«ããç©æ¥µçãªèªã¿èŸŒã¿ãã€ã³ããã¯ã¹äœæãªã©ã®ãã¯ããã¯ã䜿çšããŠããã©ãŒãã³ã¹ãæé©åããŠãã ããã`EXPLAIN`ã³ãã³ãïŒã»ãšãã©ã®ããŒã¿ããŒã¹ã·ã¹ãã ã§å©çšå¯èœïŒã¯ãã¯ãšãªã®ããã©ãŒãã³ã¹åæã«åœ¹ç«ã¡ãŸãã
- ã»ãã¥ãªãã£ïŒ SQLAlchemyãèªåçã«çæãããã©ã¡ãŒã¿ãŒåãããã¯ãšãªã䜿çšããããšã«ãããSQLã€ã³ãžã§ã¯ã·ã§ã³æ»æããã¢ããªã±ãŒã·ã§ã³ãä¿è·ããŠãã ãããåžžã«ãŠãŒã¶ãŒå ¥åãæ€èšŒãããµãã¿ã€ãºããŠãã ãããå®å šãªéä¿¡ã®ããã«HTTPSã®äœ¿çšãæ€èšããŠãã ããã
- ã¹ã±ãŒã©ããªãã£ïŒ ã¢ããªã±ãŒã·ã§ã³ãã¹ã±ãŒã©ãã«ã«ãªãããã«èšèšããŠãã ãããããã«ã¯ãå¢å ããããŒã¿éãšãŠãŒã¶ãŒã¢ã¯ã»ã¹ãã©ãã£ãã¯ãåŠçããããã«ãããŒã¿ããŒã¹ã¬ããªã±ãŒã·ã§ã³ãã·ã£ãŒãã£ã³ã°ããŸãã¯ãã®ä»ã®ã¹ã±ãŒãªã³ã°ææ³ã䜿çšããããšãå«ãŸããå ŽåããããŸãã
- ã¢ãã¿ãªã³ã°ïŒ ããã©ãŒãã³ã¹ã远跡ãããšã©ãŒãç¹å®ãã䜿çšãã¿ãŒã³ãçè§£ããããã«ãã¢ãã¿ãªã³ã°ãšãã®ã³ã°ãå®è£ ããŠãã ãããããŒã¿ããŒã¹ããã©ãŒãã³ã¹ãã¢ããªã±ãŒã·ã§ã³ããã©ãŒãã³ã¹ïŒäŸïŒAPM - Application Performance Monitoring - ããŒã«ã䜿çšïŒãããã³ãµãŒããŒãªãœãŒã¹ãç£èŠããããã®ããŒã«ã䜿çšããŠãã ããã
ãããã®å®è·µã«åŸãããšã§ãã°ããŒãã«ãªèŠèŽè ã®è€éãã«å¯ŸåŠã§ããå ç¢ã§ã¹ã±ãŒã©ãã«ãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã
äžè¬çãªåé¡ã®ãã©ãã«ã·ã¥ãŒãã£ã³ã°
SQLAlchemyãªã¬ãŒã·ã§ã³ã·ãããæ±ãéã«ããçºçããåé¡ã®ãã©ãã«ã·ã¥ãŒãã£ã³ã°ã«é¢ãããã³ããããã€ã玹ä»ããŸãã
- å€éšããŒå¶çŽãšã©ãŒïŒ å€éšããŒå¶çŽã«é¢é£ãããšã©ãŒãçºçããå Žåã¯ãæ°ããã¬ã³ãŒããæ¿å ¥ããåã«ãé¢é£ããŒã¿ãååšããããšã確èªããŠãã ãããå€éšããŒã®å€ãé¢é£ããŒãã«ã®äž»ããŒã®å€ãšäžèŽããŠããããšãå確èªããŠãã ãããããŒã¿ããŒã¹ã¹ããŒãã確èªããå¶çŽãæ£ããå®çŸ©ãããŠããããšã確èªããŠãã ããã
- N+1ã¯ãšãªåé¡ïŒ é©åãªå Žæã§ç©æ¥µçãªèªã¿èŸŒã¿ïŒçµåèªã¿èŸŒã¿ããµãã¯ãšãªèªã¿èŸŒã¿ïŒã䜿çšããããšã§ãN+1ã¯ãšãªåé¡ãç¹å®ãã察åŠããŠãã ãããã¯ãšãªãã®ã³ã°ã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ããããã¡ã€ã«ããå®è¡ãããŠããã¯ãšãªãç¹å®ããŠãã ããã
- 埪ç°ãªã¬ãŒã·ã§ã³ã·ããïŒ åŸªç°ãªã¬ãŒã·ã§ã³ã·ããïŒäŸïŒAãBãšé¢ä¿ãæã¡ãBãAãšé¢ä¿ãæã€ïŒã«ã¯æ³šæããŠãã ããããããã¯ã«ã¹ã±ãŒããããŒã¿ã®äžè²«æ§ã®åé¡ãåŒãèµ·ããå¯èœæ§ããããŸããäžå¿ èŠãªè€éããé¿ããããã«ãããŒã¿ã¢ãã«ãæ éã«èšèšããŠãã ããã
- ããŒã¿ã®äžè²«æ§ã®åé¡ïŒ ããŒã¿ã®äžè²«æ§ã確ä¿ããããã«ãã©ã³ã¶ã¯ã·ã§ã³ã䜿çšããŠãã ããããã©ã³ã¶ã¯ã·ã§ã³ã¯ããã©ã³ã¶ã¯ã·ã§ã³å ã®ãã¹ãŠã®æäœãäžç·ã«æåããããäžç·ã«å€±æããããšãä¿èšŒããŸãã
- ããã©ãŒãã³ã¹ã®åé¡ïŒ ã¯ãšãªããããã¡ã€ã«ããŠãå®è¡é床ã®é ãæäœãç¹å®ããŠãã ãããã€ã³ããã¯ã¹ã䜿çšããŠã¯ãšãªããã©ãŒãã³ã¹ãåäžãããŠãã ãããããŒã¿ããŒã¹ã¹ããŒããšãªã¬ãŒã·ã§ã³ã·ããèªã¿èŸŒã¿æŠç¥ãæé©åããŠãã ãããããŒã¿ããŒã¹ããã©ãŒãã³ã¹ã¡ããªãã¯ïŒCPUãã¡ã¢ãªãI/OïŒãç£èŠããŠãã ããã
- ã»ãã·ã§ã³ç®¡çã®åé¡ïŒ SQLAlchemyã»ãã·ã§ã³ãé©åã«ç®¡çããŠããããšã確èªããŠãã ããããªãœãŒã¹ãè§£æŸããããã«ã䜿çšåŸã¯ã»ãã·ã§ã³ãéããŠãã ãããã³ã³ããã¹ããããŒãžã£ãŒïŒäŸïŒ`with SessionLocal() as session:`ïŒã䜿çšããŠãäŸå€ãçºçããå Žåã§ãã»ãã·ã§ã³ãé©åã«éããããããã«ããŠãã ããã
- é å»¶èªã¿èŸŒã¿ãšã©ãŒïŒ ã»ãã·ã§ã³å€ã§é å»¶èªã¿èŸŒã¿ããã屿§ã«ã¢ã¯ã»ã¹ããéã«åé¡ãçºçããå Žåã¯ãã»ãã·ã§ã³ããŸã éããŠãããããŒã¿ãããŒããããŠããããšã確èªããŠãã ãããããã解決ããããã«ç©æ¥µçãªèªã¿èŸŒã¿ãŸãã¯åçèªã¿èŸŒã¿ã䜿çšããŠãã ããã
- `back_populates`å€ã®èª€ãïŒ `back_populates`ããªã¬ãŒã·ã§ã³ã·ããã®å察åŽã®å±æ§åãæ£ããåç §ããŠããããšã確èªããŠãã ãããã¹ãã«ãã¹ã¯äºæããªãåäœã«ã€ãªããå¯èœæ§ããããŸãã
- ããŒã¿ããŒã¹æ¥ç¶ã®åé¡ïŒ ããŒã¿ããŒã¹æ¥ç¶æååãšèªèšŒæ å ±ãå確èªããŠãã ãããããŒã¿ããŒã¹ãµãŒããŒãå®è¡äžã§ãã¢ããªã±ãŒã·ã§ã³ããã¢ã¯ã»ã¹å¯èœã§ããããšã確èªããŠãã ãããããŒã¿ããŒã¹ã¯ã©ã€ã¢ã³ãïŒäŸïŒPostgreSQLã®å Žåã¯`psql`ãMySQLã®å Žåã¯`mysql`ïŒã䜿çšããŠæ¥ç¶ãå¥éãã¹ãããŠãã ããã
çµè«
SQLAlchemyãªã¬ãŒã·ã§ã³ã·ãããç¹ã«å€éšããŒç®¡çãç¿åŸããããšã¯ãé©åã«æ§é åãããå¹ççã§ãä¿å®å¯èœãªããŒã¿ããŒã¹ã¢ããªã±ãŒã·ã§ã³ãäœæããããã«äžå¯æ¬ ã§ãããã®ã¬ã€ãã§æŠèª¬ãããŠããããŸããŸãªãªã¬ãŒã·ã§ã³ã·ããã®çš®é¡ãèªã¿èŸŒã¿æŠç¥ãããã³ãã¹ããã©ã¯ãã£ã¹ãçè§£ããããšã§ãè€éãªããŒã¿ã¢ãã«ãåŠçã§ãã匷åãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã倿§ã§ã°ããŒãã«ãªèŠèŽè ã®ããŒãºãæºããã¢ããªã±ãŒã·ã§ã³ãäœæããããã«ãããã©ãŒãã³ã¹ãã¹ã±ãŒã©ããªãã£ãã°ããŒãã«ãªèæ ®äºé ãªã©ã®èŠçŽ ãå¿ããªãã§ãã ããã
ãã®å æ¬çãªã¬ã€ãã¯ãSQLAlchemyãªã¬ãŒã·ã§ã³ã·ãããæ±ãããã®åŒ·åºãªåºç€ãæäŸããŸããSQLAlchemyã®ããã¥ã¡ã³ããæ¢çŽ¢ãç¶ããããŸããŸãªãã¯ããã¯ã詊ããŠçè§£ãšã¹ãã«ãåäžãããŠãã ãããããããŒã³ãŒãã£ã³ã°ïŒ